# 06장 컨트롤러
Assembled by GimunLee
# 컨트롤러
컨트롤러란 파드들을 관리하는 역할
웹 서비스처럼 오랜 시간동안 계속 실행되어야 하는 파드들을 관리할 때는 레플리케이션 컨트롤러, 레플리카 세트, 디플로이먼트
클러스터의 전체 노드에 같은 파드를 실행할 때는 데몬 세트
상태가 없는 앱을 실행하는데 사용하는 컨테이너를 상태가 있는 앱을 실행할 때 사용하도록 만드는 스테이트풀세트
1회성 작접을 할 때 사용하는 잡 , 주기적인 배치 작업을 실행할 때 사용하는 크론잡
이처럼 다양한 목적에 맞게 사용할 수 있는 컨트롤러가 있다는 것이 쿠버네티스의 큰 장점
# 레플리케이션 컨트롤러(Replication Controller)
- 쿠버네티스 프로젝트의 초기부터 있었던 가장 기본적인 컨트롤러
- 지정한 숫자만큼의 파드가 항상 클러스터 안에서 실행되도록 관리
- 요즘에는 비슷한 역할을 하는 레플리카세트를 사용
# 레플리카세트(Replicaset)
레플리카세트는 레플레케이션 컨트롤러의 발전형으로, 레플리케이션 컨트롤러와 같은 동작을 하지만, 집합 기반의 셀렉터(in, notin, exists)를 지원하는 차이점 존재
레플리케이션 컨트롤러는 kubectl에서 rolling-update 옵션을 사용할 수 있지만 레플리카세트는 사용할 수 없다는 차이 존재
레플리카세트를 사용하는데 rolling-update 옵션이 필요할 때는 디플로이먼트 사용
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx-replicaset
spec:
template:
metadata:
name: nginx-replicaset
labels:
app: nginx-replicaset # selector에서 쓰일 이름
spec:
containers:
- name: nginx-replicaset
image: nginx
ports:
- containerPort: 80
replicas: 3 # 유지할 파드의 개수
selector:
matchLabels:
app: nginx-replicaset # 어떤 레이블의 파드를 선택해서 관리할지 설정
# 레플리카세트와 파드의 연관 관계
파드는 레이블 기준으로 관리하므로 레플리카세트와 파드는 느슨하게 결합되어 있어, 수정, 삭제, 생성에 용이함
레플리카세트 삭제를 파드에 영향을 안 주고 삭제시킬 수 있음
$ kubectl delete replicaset nginx-replicaset --cascade=false
# 디플로이먼트(Deployment)
- 쿠버네티스에서 상태가 없는 앱을 배포할 때 사용하는 가장 기본적인 컨트롤러
- 디플로이먼트는 레플리카세트를 관리하면서 앱 배포를 더 세밀하게 관리
- 단순히 실행시켜야 할 파드 개수를 유지하는 것뿐 아니라 앱을 배포할 때 롤링 업데이트하거나, 앱 배포 도중 잠시 멈췄다 다시 배포할 수 있음
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-deployment
spec:
replicas: 3 # 실행할 파드의 수 설정
selector:
matchLabels:
app: nginx-deployment # metadata.labels.app 과 같은 값을 설정
template:
metadata:
labels:
app: nginx-deployment
spec:
containers:
- name: nginx-deployment # 실제 사용하려는 컨테이너 이름
image: nginx # 컨테이너 이미지
ports:
- containerPort: 80 # 포트
# 디플로이먼트 수정
- 디플로이먼트 설정을 변경할 때마다 새로운 레플리카세트가 생성되고 그에 맞게 파드가 변경됨
$ kubectl set image deployment/nginx-deployment nginx-deployment=nginx:1.191
$ kubectl edit deploy nginx-deployment
# 편집기 시작
# 편집기 종료 후
deployment.extentions/nginx-deployment edited
# 디플로이먼트 롤백하기
# 정보 확인
$ kubectl rollout history deploy nginx-deployment
# 상세 내용 확인
$ kubectl rollout history deploy nginx-deployment --revision=3
# 현재 리비전을 되돌림
$ kubcetl rollout undo deploy nginx-deployment
# 특정 리비전(3)으로 실행 중인 파드 되돌리기
$ kubectl rollout undo deploy nginx-deployment --to-revision=3
- 되돌릴 수 있는 리비전 숫자는 디플로이먼트의 템플릿의
.spec.revisionHistoryLimit
필드 값(default: 10)
# 파드 개수 조정하기
- 실행 중인 디플로이먼트의 파드 개수를 조정하려면
kubectl scale
명령 실행
$ kubectl scale deploy nginx-deployment --replicas=5
# 디플로이먼트 배포 정리, 배포 재개, 재시작하기
kubectl rollout
명령을 이용해서 진행 중인 배포를 잠시 멈췄다가 다시 시작할 수 있음
# 업데이트 멈추기
$ kubectl rollout pause deploy/nginx-deployment
# 재개
$ kubectl rollout resume deploy/nginx-deployment
# 디플로이먼트 상태
- 배포 중에는 디플로이먼트 상태가 변함
# 진행(Progressing)
- 디플로이먼트가 새로운 레플리카세트를 만들 때
- 디플로이먼트가 새로운 레플리카세트의 파드 개수를 늘릴 때
- 디플로이먼트가 예전 레플리카세트의 파드 개수를 줄일 때
- 새로운 파드가 준비 상태가 되거나 이용 가능한 상태가 되었을 때
# 완료(Complete)
- 디플로이먼트가 관리하는 모든 레플리카세트가 업데이 완료되었을 때
- 모든 레플리카세트가 사용 가능해졌을 때
- 예전 레플리카세트가 모두 종료되었을 때
# 실패(Fail)
- 쿼터 부족
- readinessProbe 진단 실패
- 컨테이너 이미지 가져오기 에러
- 권한 부족
- 제한 범위 초과
- 앱 실행 조건을 잘못 지정
$ kubectl decribe deploy nginx-deployment
Conditions:
Type Status Reason
---- ------ ------
Available True MinimunReplicasAvailable
Progressing False ProgressDeadlineExceeded
# 데몬세트
- 데몬세트는 클러스터 전체 노드에 특정 파드를 실행할 때 사용하는 컨트롤러
- 클러스터 안에 새롭게 노드가 추가되었을 때 데몬세트가 자동으로 해당 노드에 파드 실행
- 데몬세트트 보통 로그 수집기를 실행하거나 노드를 모니터링하는 모니터링용 데몬 등 클러스터 전체에 항상 실행시켜두어야 하는 파드에 사용
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system # 관리용 파드나 설정에 해당하므로 kube-system 네임스페이스 설정
labels: # 오브젝트를 식별하는 레이블
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
updateStrategy:
type: RollingUpdate # Ondelete와 RollingUpdate 두 가지 값중 하나 선택
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
containers:
- name: fluentd-elasticsearch
image: fluent/fluentd-kubernetes-daemonset:elasticsearch
env:
- name: testenv
value: value
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
# 스테이트풀세트
- 스테이트풀세트는 상태가 있는 파드들을 관리하는 컨트롤러
- 볼륨을 사용해서 특정 데이터를 저장한 후 파드를 재시작했을 때 해당 데이터를 유지
- 여러 개의 파드 사이에 순서를 지정해서 실행되도록 할 수도 있음
apiVersion: v1 # 스테이트풀세트에서 사용할 서비스 설정
kind: Service
metadata:
name: nginx-statefulset-service
labels:
app: nginx-statefulset-service
spec:
ports:
- port: 80
name: web
clusterIP: None
selector:
app: nginx-statefulset-service
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web # 스테이트풀세트의 이름
spec:
selector:
matchLabels:
app: nginx-statefulset
serviceName: "nginx-statefulset-service"
replicas: 3
template:
metadata:
labels:
app: nginx-statefulset
spec:
terminationGracePeriodSeconds: 10 # 그레이스풀의 대기 시간 설정
containers:
- name: nginx-statefulset
image: nginx
ports:
- containerPort: 80
name: web%
그레이스풀(gracefull): 실행 중인 프로세스를 종료할 때 바로 종료하는 것이 아니라 하던 작업을 마무리하고 정상적으로 종료하는 것을 의미
.spec.podManagement
Policy 필드를 이용해 순서를 없앨 수도 있음
# 잡(Job)
- 잡은 실행된 후 종료해야 하는 성격의 작업을 실행시킬 때 사용하는 컨트롤러
- 특정 개수만큼의 파드를 정상적으로 실행 종료함을 보장함
- 파드 실행 실패, 하드웨어 장애 발생, 노드 재시작 등 문제가 발생하면 다시 파드 실행
- 잡 하나가 파드 여러 개 실행 가능
apiVersion: batch/v1 # 잡이 사용하는 버전
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] # 원주율 계산 펄(perl) 명령
restartPolicy: Never # 항상 성공으로 끝나도록 설정(OnFailure: 비정상적으로 실행 종료된 파드 관리)
backoffLimit: 4 # 최대 몇 번까지 재시작할 것인지 설정
# 잡 병렬설 관리
- 잡 하나가 몇 개의 파드를 동시에 실행할지를 '잡 병렬성'이라고 함
# 잡의 종류
# 단일 잡
- 파드 하나만 실행
- 파드가 정상적으로 실행 종료(파드 생명 주기가 Succeeded)되면 잡 실행을 완료
.spec.completions
와.spec.parallelism
필드를 설정하지 않음
# 완료 개수가 있는 병렬 잡
.spec.completions
필드 값으로 양수를 설정. 필드 값이 1이면 정상적으로 실행 종료된 파드가 1개만 생겨도 잡이 완료.spec.parallelism
필드는 설정하지 않거나 기본값인 1로 설정
# 워크 큐가 있는 병렬 잡
.spec.completions
필드는 설정하지 않고,.spec.parallelism
필드는 양수로 설정- 파드 각각은 정상적으로 실행 종료됐는지를 독립적으로 결정 가능
- 대기열에 있는 작업들이 모두 동시에 실행될 수 있음
- 파드 하나라도 정상적으로 실행 종료되면 새로운 파드가 실행되지 않음
- 최소한 파드 1개가 정상적으로 종료된 후 모든 파드가 실행 종료되면, 잡이 정상적으로 종료됨
- 파드 1개가 정상적으로 실행 종료되면 다른 파드는 더 이상 동작하지 않거나 어떤 작업 처리 결과를 내지 않음
# 잡 패턴
- 잡에서 파드를 병렬로 실행했을 때 파드 각각이 서로 통신하면서 동작하지 않음
# 잡의 일반적인 사용 패턴
- 잡을 생성하는 오버헤드가 크기 때문에 작업마다 잡을 하나씩 생성해 사용하는 것보다는 모든 작업을 관리하는 잡 하나를 사용하는 것이 좋음
- 작업 개수만큼의 파드를 생성하는 것보다 파드 하나가 여러 개의 작업을 처리하는 것이 좋음
- 워크 큐를 사용한다면 카프카나 RabbitMQ 같은 큐 서비스로 워크 큐를 구현하도록 깆ㄴ 프로그램이나 컨테이너를 수정해야함
# 크론잡(CronJob)
- 크론잡은 잡을 시간 기준으로 관리하도록 생성
- 지정한 시간에 한번만 잡을 실행하거나 지정한 시간동안 주기적으로 잡을 반복 실행 가능
# Referenses
- 쿠버네티스 입문 - 90가지 예제로 배우는 컨테이너 관리 자동화 표준 / 동양북스